package com.zhihao.trigger.job;

import com.xxl.job.core.handler.annotation.XxlJob;
import com.zhihao.domain.strategy.model.valobj.StrategyAwardStockKeyVO;
import com.zhihao.domain.strategy.service.IRaffleStock;
import io.micrometer.core.annotation.Timed;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author Jackson
 * @create 2025/3/14 21:23
 * @description
 *      redis延迟队列获取 根据redis扣减库存消息 update 数据库奖品库存
 *          更新策略奖品库存的任务(消费者)
 *              更新奖品库存任务；为了不让更新库存的压力打到数据库中，这里采用了redis更新缓存库存，异步队列更新数据库，数据库表最终一致即可。
 */
@Slf4j
@Component
public class UpdateAwardStockJob {

    @Resource
    private IRaffleStock raffleStock;

//    @Qualifier("redisson")
//    @Autowired
    @Resource
    private RedissonClient redisson;

//    @Scheduled(cron = "0/5 * * * * ?")
    @Timed(value = "UpdateAwardStockJob", description = "更新奖品库存任务")
    @XxlJob("UpdateAwardStockJob")
    public void raffleAwardStockSubConsumer() {
        RLock lock = redisson.getLock("big-market-UpdateAwardStockJob");
        boolean isLocked = false;

        try {
            isLocked = lock.tryLock(3, 0, TimeUnit.SECONDS);
            if (!isLocked) return;

//            log.info("定时任务，更新奖品消耗库存【延迟队列获取，降低对数据库的更新频次，不要产生竞争】");
            StrategyAwardStockKeyVO strategyAwardStockKeyVO = raffleStock.takeQueueValue();
            if (null == strategyAwardStockKeyVO) return;
            log.info("定时任务，更新奖品消耗库存成功 strategyId:{} awardId:{}", strategyAwardStockKeyVO.getStrategyId(), strategyAwardStockKeyVO.getAwardId());
            raffleStock.updateStrategyAwardStock(strategyAwardStockKeyVO.getStrategyId(), strategyAwardStockKeyVO.getAwardId());
        } catch (Exception e) {
            log.error("定时任务，更新奖品消耗库存失败", e);
        }finally {
            if (isLocked){
                lock.unlock();
            }
        }
    }

}
